'''
Created on 24/03/2009

@author: eh01
'''
from im.ds.dsstub import DSStub
from im.event import eventconstants
from im.event.eventmanager import EventManager
from im.handler.connectivitytestrequesthandler import \
    ConnectivityTestHTTPRequestHandler, ConnectivityTestWebServiceRequestHandler
from im.handler.connectivitytestresponsehandler import \
    ConnectionTestHTTPResponseHandler, ConnectivityTestWebServiceResponseHandler
from im.handler.httperrorhandler import HTTPErrorHandler
from im.handler.hubmessagehandler import HubMessageHandler
from im.handler.imhttpdelegaterequesthandler import IMHTTPDelegateRequestHandler
from im.handler.imhttpresponsehandler import IMHTTPResponseHandler
from im.handler.sendtohubhandler import SendToHubHandler
from im.handler.speara2ahandler import SPEARA2AHandler
from im.handler.httprequestgetstaticpagehandler import HTTPRequestGETStaticPageHandler
from im.hub.hublistener import HubListener
from im.webserver.imhttpserver import IMHTTPServer
from im.handler.speara2afaulthandler import SPEARA2AFaultWebServiceResponseHandler,\
    SPEARA2AFaultHTTPResponseHandler
from im.handler.huberrorhandler import HubErrorHandler
from im.timerservice.timerservicemanager import TimerServiceManager
from im.handler.responsetimeouthandler import ResponseTimeoutHandler
from im.handler.publicapplicationstatusrequesthanlder import PublicApplicationStatusHTTPRequestHandler,\
    PublicApplicationStatusWebServiceRequestHandler
from im.handler.publicapplicationstatusresponsehandler import PublicApplicationStatusWebServiceResponseHandler,\
    PublicApplicationStatusTestHTTPResponseHandler
from im.handler.httprequestgetindexhandler import HTTPRequestGETIndexHandler
from im.imconfig import IMConfig
import sys

class Initializer():

    __server = None
    __hub_listener = None
    __dsstub = None
    
    
    def initialize_db_stub(self):
        self.__dsstub = DSStub()
        imconfig = IMConfig(config_file_absolute_path)
        self.__dsstub.set_IM_Config(imconfig)
        
    def initialize_event_manager(self):
        # override the default get_eventHandlers method at a class level for testing purposes
        instancemethodEventHandlers = type(EventManager.get_eventHandlers)
        EventManager.get_eventHandlers = instancemethodEventHandlers(get_eventHandlers_override, None, EventManager)
        eventManager = EventManager()
        eventManager.start()

    def initialize_web_server(self):
        self.__server = IMHTTPServer(self.__dsstub.get_http_server_port())
        self.__server.start()   
    
    def initialize_hub_listener(self):
        self.__hub_listener = HubListener(self.__dsstub.get_node_id())
        self.__hub_listener.start()
        
    def initialize_timer_manager(self):
        timer_manager = TimerServiceManager()
        timer_manager.start()
        
    def shutdown_event_manager(self):
        EventManager().stop()
        
    def shutdown_web_server(self):
        self.__server.stop()
    
    def shutdown_hub_listener(self):
        self.__hub_listener.stop_listener()
    
    def shutdown_timer_manager(self):
        TimerServiceManager().stop()
        
    def initialize(self):
        self.initialize_db_stub()
        self.initialize_event_manager()
        self.initialize_web_server()
        self.initialize_hub_listener()
        self.initialize_timer_manager()
        print 'Initialization Complete'
    
    def shutdown(self):
        self.shutdown_event_manager()
        self.shutdown_web_server()
        self.shutdown_hub_listener()
        self.shutdown_timer_manager()
        print 'Shutdown Complete'

def get_eventHandlers_override(self):
    im_http_delegagte_request_handler = IMHTTPDelegateRequestHandler()
    http_request_get_static_page_handler = HTTPRequestGETStaticPageHandler()
    http_error_handler = HTTPErrorHandler()
    connectivity_test_request_handler = ConnectivityTestHTTPRequestHandler()
    im_http_response_handler = IMHTTPResponseHandler()
    send_to_hub_handler = SendToHubHandler()
    hub_message_handler = HubMessageHandler()
    connectivity_test_http_response_handler = ConnectionTestHTTPResponseHandler()
    connectivity_test_web_service_request_handler = ConnectivityTestWebServiceRequestHandler()
    spear_a2a_handler = SPEARA2AHandler()
    connectivity_test_web_service_response_handler = ConnectivityTestWebServiceResponseHandler()
    spear_a2a_fault_webservice_response_handler = SPEARA2AFaultWebServiceResponseHandler()
    spear_a2a_fault_http_response_handler = SPEARA2AFaultHTTPResponseHandler()
    hub_error_handler = HubErrorHandler()
    response_timeout_handler = ResponseTimeoutHandler()
    public_application_status_test_http_request_handler = PublicApplicationStatusHTTPRequestHandler()
    public_application_status_test_web_service_request_handler = PublicApplicationStatusWebServiceRequestHandler()
    public_application_status_test_web_service_response_handler = PublicApplicationStatusWebServiceResponseHandler()
    public_application_status_test_http_response_handler = PublicApplicationStatusTestHTTPResponseHandler()
    http_request_get_index_handler = HTTPRequestGETIndexHandler()
    eventHandlers = {
                     eventconstants.HTTP_REQUEST_EVENT_TYPE:im_http_delegagte_request_handler,
                     eventconstants.HTTP_REQUEST_GET_STATIC_PAGE:http_request_get_static_page_handler,
                     eventconstants.HTTP_ERROR_EVENT_TYPE:http_error_handler,
                     eventconstants.HTTP_REQUEST_POST_CONNECTIVITY_TEST_EVENT_TYPE:connectivity_test_request_handler,
                     eventconstants.CONNECTIVITY_TEST_REQUEST_EVENT_TYPE:connectivity_test_web_service_request_handler,
                     eventconstants.CONNECTIVITY_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE:connectivity_test_web_service_response_handler,
                     eventconstants.CONNECTIVITY_TEST_RESPONSE_EVENT_TYPE:connectivity_test_http_response_handler,
                     eventconstants.HTTP_REQUEST_POST_APPLICATION_STATUS_TEST_EVENT_TYPE:public_application_status_test_http_request_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_REQUEST_EVENT_TYPE:public_application_status_test_web_service_request_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE:public_application_status_test_web_service_response_handler,
                     eventconstants.PUBLIC_APPLICATION_STATUS_TEST_RESPONSE_MESSAGE_TYPE:public_application_status_test_http_response_handler,
                     eventconstants.HTTP_RESPONSE_EVENT_TYPE:im_http_response_handler,
                     eventconstants.SEND_TO_HUB_EVENT_TYPE:send_to_hub_handler,
                     eventconstants.HUB_MESSAGE_EVENT_TYPE:hub_message_handler,
                     eventconstants.SEND_TO_SPEAR_EVENT_TYPE:spear_a2a_handler,
                     eventconstants.SPEAR_A2A_FAULT_WEB_SERVICE_EVENT_TYPE:spear_a2a_fault_webservice_response_handler,
                     eventconstants.SPEAR_A2A_FAULT_HTTP_EVENT_TYPE:spear_a2a_fault_http_response_handler,
                     eventconstants.HUB_ERROR_EVENT_TYPE:hub_error_handler,
                     eventconstants.RESPONSE_TIMEOUT_EVENT_TYPE:response_timeout_handler,
                     eventconstants.HTTP_REQUEST_GET_INDEX_EVENT_TYPE:http_request_get_index_handler
                     }        
    return eventHandlers

if __name__ == '__main__':
    
    config_file_absolute_path = sys.argv[1]
    initializer = None
    try:
        initializer = Initializer()
        initializer.initialize()
        if DSStub().is_allow_keyboard_interrupt():
            # wait for KeyboardInterrupts
            sys.stdin.read()
            print 'Stopping'
    except KeyboardInterrupt:
        initializer.shutdown()